var Net = require("Net")

var RouteHandler = require("RouteHandler");
var Client2ProxyHandler = require("Client2ProxyHandler");
var routeCmds = require("Client2routeCmds");
var proxyCmds = require("Client2proxyCmds");

var ProxyNet = {
}

ProxyNet.conn = function (onConnReady) {
    //绑定准备好后的回调
    this.onReady = onConnReady;

    //route协议解析器初始化
    var routeHandler = new RouteHandler();
    routeHandler.handlerRouteProxyResponse = function (rsp) {
        //断开route的链接
        Net.disConnect();

        if (rsp.errorNo != 0) {
            throw "route response a error " + rsp.errorNo;
        }

        cc.info("recevie route response ip:" + rsp.ip);

        //配置 proxy 链接
        ProxyNet.url = PROXY_URL.format(rsp.ip, rsp.port);
    }

    //proxy协议解析器初始化
    var proxyHandler = new Client2ProxyHandler();
    proxyHandler.handlerProxyMsgResponse = function (rsp) {

        if (rsp.errorNo != 0) {
            throw "proxy response error " + rsp.errorNo;
        }

        var bytebuf = new Bytebuf(rsp.result);
        //读取协议号
        var commandId = bytebuf.readInt();
        var commandModuleId = ProxyNet.getCommandModuleId(commandId);
        var moduleHandler = MODULE_MAPPING[commandModuleId];
        moduleHandler.exec(commandId, bytebuf);
    }

    proxyHandler.handlerHeartBeatResponse = function (rsp) {
        cc.info("收到服务器心跳..咚咚")
    }

    //开启route链接
    Net.doConnect(ROUTE_URL, ProxyNet.onRouteConn, ProxyNet.onReceive, ProxyNet.onRouteClose, ProxyNet.onError);
}

ProxyNet.onRouteClose = function () {
    if (ProxyNet.url) {
        cc.info("connect to proxy %s".format(ProxyNet.url));
        Net.doConnect(ProxyNet.url, ProxyNet.onProxyConn, ProxyNet.onReceive, ProxyNet.onProxyClose, ProxyNet.onError);
    }
}

ProxyNet.onError = function (error) {
    cc.log(error);
    SysEvent.emit(EVENT_NET_CONNERROR);
}

ProxyNet.onRouteConn = function () {
    var bytebuf = new Bytebuf();
    var routeReq = new routeCmds.RouteProxyRequest();
    routeReq.writeTo(bytebuf);
    Net.send(bytebuf.buff);
    cc.info("send route request");
}

ProxyNet.onProxyConn = function () {
    //正式链接开始后的操作
    if (ProxyNet.onReady) {
        ProxyNet.onReady();
    }
}

//开启心跳
ProxyNet.startHeartbeat = function () {
    ProxyNet.heartbeat = setInterval(function () {
        var bytebuf = new Bytebuf();
        var heartbeat = new proxyCmds.HeartBeatRequest();
        heartbeat.writeTo(bytebuf);
        Net.send(bytebuf.buff);
    }, 8000);
}

ProxyNet.onReceive = function (commandMsg) {
    //commandMsg:{type:'message',data:'arraybuf'}
    var bytebuf = new Bytebuf(commandMsg.data);
    //读取长度位
    bytebuf.readInt();
    //读取协议
    var commandId = bytebuf.readInt();

    cc.log("receive cmd [%s]".format(commandId));

    var commandModuleId = ProxyNet.getCommandModuleId(commandId);
    var moduleHandler = MODULE_MAPPING[commandModuleId];
    moduleHandler.exec(commandId, bytebuf);
};

ProxyNet.onProxyClose = function () {
    cc.log("lost proxy connection");
    SysEvent.emit(EVENT_NET_CONNERROR);
}

ProxyNet.send = function (service, allotParam, dataObj) {
    if (typeof dataObj.writeTo == 'undefined') {
        throw "ProxyNet dont find writeTo function on obj" + dataObj;
    }

    if (!Net.isConnectd()) {
        throw "the net is not connect";
    }

    var originBuf = new Bytebuf();
    dataObj.writeTo(originBuf);

    var proxyReq = new proxyCmds.ProxyMsgRequest();
    proxyReq.service = service;
    proxyReq.allotParam = allotParam;
    proxyReq.msg = originBuf.getBytes();

    var proxyBuf = new Bytebuf();
    proxyReq.writeTo(proxyBuf);
    Net.send(proxyBuf.buff);

    if (DEBUG) {
        cc.log("send msg to %s with allotParam [%s] :".format(service, allotParam));
        dump(dataObj);
    }
}

ProxyNet.getCommandModuleId = function (commandId) {
    return (commandId >> 16) & 0x00FF;
}

module.exports = ProxyNet;
